bitkeeper revision 1.1159.180.1 (419dbad8-u4Z8SxMk3S7dzh4pdErPg)
authorkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>
Fri, 19 Nov 2004 09:20:24 +0000 (09:20 +0000)
committerkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>
Fri, 19 Nov 2004 09:20:24 +0000 (09:20 +0000)
I/O bitmap cleanups.

xen/arch/x86/domain.c
xen/arch/x86/setup.c
xen/arch/x86/traps.c
xen/common/physdev.c
xen/include/asm-x86/processor.h
xen/include/xen/sched.h

index 0ba36df0c07ba34c1fc19a0ab8de415a35df1f9a..69e1506a02d1ba0a45f93114924ca210742cfde2 100644 (file)
@@ -389,60 +389,23 @@ void switch_to(struct domain *prev_p, struct domain *next_p)
         write_ptbase(&next_p->mm);
     }
 
-    if ( unlikely(prev_p->io_bitmap != NULL) || 
-         unlikely(next_p->io_bitmap != NULL) )
+    if ( unlikely(prev_p->thread.io_bitmap != NULL) )
     {
-        if ( next_p->io_bitmap != NULL )
-        {
-            /* Copy in the appropriate parts of the IO bitmap.  We use the
-             * selector to copy only the interesting parts of the bitmap. */
-
-            u64 old_sel = ~0ULL; /* IO bitmap selector for previous task. */
-
-            if ( prev_p->io_bitmap != NULL)
-            {
-                old_sel = prev_p->io_bitmap_sel;
-
-                /* Replace any areas of the IO bitmap that had bits cleared. */
-                for ( i = 0; i < sizeof(prev_p->io_bitmap_sel) * 8; i++ )
-                    if ( !test_bit(i, &prev_p->io_bitmap_sel) )
-                        memcpy(&tss->io_bitmap[i * IOBMP_SELBIT_LWORDS],
-                               &next_p->io_bitmap[i * IOBMP_SELBIT_LWORDS],
-                               IOBMP_SELBIT_LWORDS * sizeof(unsigned long));
-            }
-
-            /* Copy in any regions of the new task's bitmap that have bits
-             * clear and we haven't already dealt with. */
-            for ( i = 0; i < sizeof(prev_p->io_bitmap_sel) * 8; i++ )
-            {
-                if ( test_bit(i, &old_sel)
-                     && !test_bit(i, &next_p->io_bitmap_sel) )
-                    memcpy(&tss->io_bitmap[i * IOBMP_SELBIT_LWORDS],
-                           &next_p->io_bitmap[i * IOBMP_SELBIT_LWORDS],
-                           IOBMP_SELBIT_LWORDS * sizeof(unsigned long));
-            }
-
-            tss->bitmap = IO_BITMAP_OFFSET;
-
-       }
-        else
-        {
-            /* In this case, we're switching FROM a task with IO port access,
-             * to a task that doesn't use the IO bitmap.  We set any TSS bits
-             * that might have been cleared, ready for future use. */
-            for ( i = 0; i < sizeof(prev_p->io_bitmap_sel) * 8; i++ )
-                if ( !test_bit(i, &prev_p->io_bitmap_sel) )
-                    memset(&tss->io_bitmap[i * IOBMP_SELBIT_LWORDS],
-                           0xFF, IOBMP_SELBIT_LWORDS * sizeof(unsigned long));
+        for ( i = 0; i < sizeof(prev_p->thread.io_bitmap_sel) * 8; i++ )
+            if ( !test_bit(i, &prev_p->thread.io_bitmap_sel) )
+                memset(&tss->io_bitmap[i * IOBMP_BYTES_PER_SELBIT],
+                       ~0U, IOBMP_BYTES_PER_SELBIT);
+        tss->bitmap = IOBMP_INVALID_OFFSET;
+    }
 
-            /*
-             * a bitmap offset pointing outside of the TSS limit
-             * causes a nicely controllable SIGSEGV if a process
-             * tries to use a port IO instruction. The first
-             * sys_ioperm() call sets up the bitmap properly.
-             */
-            tss->bitmap = INVALID_IO_BITMAP_OFFSET;
-       }
+    if ( unlikely(next_p->thread.io_bitmap != NULL) )
+    {
+        for ( i = 0; i < sizeof(next_p->thread.io_bitmap_sel) * 8; i++ )
+            if ( !test_bit(i, &next_p->thread.io_bitmap_sel) )
+                memcpy(&tss->io_bitmap[i * IOBMP_BYTES_PER_SELBIT],
+                       &next_p->thread.io_bitmap[i * IOBMP_BYTES_PER_SELBIT],
+                       IOBMP_BYTES_PER_SELBIT);
+        tss->bitmap = IOBMP_OFFSET;
     }
 
     set_current(next_p);
index b565bbd083daa4a2698e8c4877959fa4f04ad74b..7ed4bf0744b72f7c3831e52d5363ff1422a9d2d0 100644 (file)
@@ -268,7 +268,7 @@ void __init cpu_init(void)
         panic("CPU#%d already initialized!!!\n", nr);
     printk("Initializing CPU#%d\n", nr);
 
-    t->bitmap = INVALID_IO_BITMAP_OFFSET;
+    t->bitmap = IOBMP_INVALID_OFFSET;
     memset(t->io_bitmap, ~0, sizeof(t->io_bitmap));
 
     /* Set up GDT and IDT. */
index 3d11210dac68fc38b2d3f6b6e8fd16df306c2b54..7b7c07142c6673d63a85ac80971c598980e5532c 100644 (file)
@@ -721,7 +721,7 @@ void __init trap_init(void)
     tss->cs     = __HYPERVISOR_CS;
     tss->eip    = (unsigned long)do_double_fault;
     tss->eflags = 2;
-    tss->bitmap = INVALID_IO_BITMAP_OFFSET;
+    tss->bitmap = IOBMP_INVALID_OFFSET;
     _set_tssldt_desc(gdt_table+__DOUBLEFAULT_TSS_ENTRY,
                      (int)tss, 235, 0x89);
 
index b1c16d00b332741c3573ac8b62d2f0482af2a680..728a8fe07fad28b66c3bbfacb8a39fccd5c77014 100644 (file)
@@ -169,16 +169,16 @@ int physdev_pci_access_modify(
 
     /* Now, setup access to the IO ports and memory regions for the device. */
 
-    if ( p->io_bitmap == NULL )
+    if ( p->thread.io_bitmap == NULL )
     {
-        if ( (p->io_bitmap = xmalloc(IO_BITMAP_BYTES)) == NULL )
+        if ( (p->thread.io_bitmap = xmalloc(IOBMP_BYTES)) == NULL )
         {
             rc = -ENOMEM;
             goto out;
         }
-        memset(p->io_bitmap, 0xFF, IO_BITMAP_BYTES);
+        memset(p->thread.io_bitmap, 0xFF, IOBMP_BYTES);
 
-        p->io_bitmap_sel = ~0ULL;
+        p->thread.io_bitmap_sel = ~0ULL;
     }
 
     for ( i = 0; i < DEVICE_COUNT_RESOURCE; i++ )
@@ -195,13 +195,8 @@ int physdev_pci_access_modify(
                  "for device %s\n", dom, r->start, r->end, pdev->slot_name);
             for ( j = r->start; j < r->end + 1; j++ )
             {
-                clear_bit(j, p->io_bitmap);
-                /* Record that we cleared a bit using bit n of the selector:
-                 * n = (j / (4 bytes in a word * 8 bits in a byte))
-                 *     / number of words per selector bit
-                 */
-                clear_bit((j / (8 * 4)) / IOBMP_SELBIT_LWORDS,
-                          &p->io_bitmap_sel);
+                clear_bit(j, p->thread.io_bitmap);
+                clear_bit(j / IOBMP_BITS_PER_SELBIT, &p->thread.io_bitmap_sel);
             }
         }
 
index e8dde063e8c9f5d277931c90551ce5bd0b1bc29a..81d35ad3248e1a01ac836586b942af2a77abd062 100644 (file)
@@ -244,15 +244,11 @@ static inline void clear_in_cr4 (unsigned long mask)
             :"ax");
 }
 
-/*
- * Size of io_bitmap in longwords:
- * For Xen we support the full 8kbyte IO bitmap but use the io_bitmap_sel field
- * to avoid a full 8kbyte copy when switching to domains with bits cleared.
- */
-#define IO_BITMAP_SIZE 2048
-#define IO_BITMAP_BYTES (IO_BITMAP_SIZE * 4)
-#define IO_BITMAP_OFFSET offsetof(struct tss_struct,io_bitmap)
-#define INVALID_IO_BITMAP_OFFSET 0x8000
+#define IOBMP_BYTES             8192
+#define IOBMP_BYTES_PER_SELBIT  (IOBMP_BYTES / 64)
+#define IOBMP_BITS_PER_SELBIT   (IOBMP_BYTES_PER_SELBIT * 8)
+#define IOBMP_OFFSET            offsetof(struct tss_struct,io_bitmap)
+#define IOBMP_INVALID_OFFSET    0x8000
 
 struct i387_state {
     u8 state[512]; /* big enough for FXSAVE */
@@ -293,7 +289,7 @@ struct tss_struct {
     u16 trace;
 #endif
     u16 bitmap;
-    u32 io_bitmap[IO_BITMAP_SIZE+1];
+    u8  io_bitmap[IOBMP_BYTES];
     /* Pads the TSS to be cacheline-aligned (total size is 0x2080). */
     u32 __cacheline_filler[5];
 };
@@ -335,6 +331,11 @@ struct thread_struct {
     /* Bounce information for propagating an exception to guest OS. */
     struct trap_bounce trap_bounce;
 
+    /* I/O-port access bitmap. */
+    u64 io_bitmap_sel; /* Selector to tell us which part of the IO bitmap are
+                        * "interesting" (i.e. have clear bits) */
+    u8 *io_bitmap; /* Pointer to task's IO bitmap or NULL */
+
     /* Trap info. */
 #ifdef __i386__
     int                fast_trap_idx;
index d7c8824d0a6118cb146564b85e1539654f4565bf..d449f6bfaa5ae136a17a0d803693672c95d17a19 100644 (file)
@@ -104,14 +104,6 @@ struct domain
     spinlock_t       pcidev_lock;
     struct list_head pcidev_list;
 
-    /* The following IO bitmap stuff is x86-dependent. */
-    u64 io_bitmap_sel; /* Selector to tell us which part of the IO bitmap are
-                        * "interesting" (i.e. have clear bits) */
-
-    /* Handy macro - number of bytes of the IO bitmap, per selector bit. */
-#define IOBMP_SELBIT_LWORDS (IO_BITMAP_SIZE / 64)
-    unsigned long *io_bitmap; /* Pointer to task's IO bitmap or NULL */
-
     unsigned long flags;
     unsigned long vm_assist;